<?php
/**
 *	KLF Framework
 *
 *	@author Kristian Oye <kristianoye@gmail.com> 
 *	@copyright (C) 2010-2011, Kristian Oye
 */
namespace KLF\System\Web\Routing
{
	use KLF\System\Errors\KRouteException;

	use KLF\System\KType;
	use KLF\System\KPropertyContext;
	use KLF\System\Errors\KArgumentException;
	use KLF\System\Collections\KDictionary as KDictionary;
	
	/**
	 *  Class KRouteCollection
	 *
	 *  @package KLF\System\Web\Routing
	 *  @access public
	 *  @author Kristian Oye <kristianoye@gmail.com>
	 *  @since 0.1
	 *  @version 0.1
	 *  
	 *  @method KRouteCollection NewInstance
	 */
	class KRouteCollection extends KDictionary
	{
		/**
		 * Constructs a new KRouteCollection
		 *
		 * @author Kristian Oye <kristianoye@gmail.com>
		 * @since 0.1
		*/
		public function __construct()
		{
			parent::__construct(KType::GetType('string'), KRoute::GetType());
		}
		
		/**
		 * Adds a new route to the collection.
		 * 
		 * @see KLF\System\Collections.KDictionary::Add()
		 */
		public function Add(KRoute $route)
		{
			$key = sprintf("__unnamedRoute_%02d", $this->count()); 
			return parent::Add($key, $route);
		}
		
		/**
		 * Map a named-route into the collection.
		 * 
		 * @param string $name
		 * @param string $url
		 * @param mixed $arg1
		 * @param mixed $arg2
		 * @param mixed $arg3
		 * @return KRouteCollection
		 */
		public function MapRoute(array $args)
		{
			if ($this->ValidateRoute($args))
			{
				$route = new KRoute($args);
				parent::Add($route->Name, $route);
			}
			return $this;
		}
		
		/**
		 * Ignores a particular pattern.
		 *
		 * @author Kristian Oye <kristianoye@gmail.com>
		 * @since 0.1
		 * @param KRoute The route to ignore.
		 * @return KRouteCollection Returns a reference to the KRouteCollection.
		*/
		public function IgnoreRoute(KRoute $route)
		{
			$route->RouteHandler = new KIgnoreRouteHandler();
			
			return $this->Add($route);
		}
		
		/**
		 * 
		 * Enter description here ...
		 * @param unknown_type $route
		 */
		protected function ValidateRoute($route)
		{
			if (!is_array($route))
			{
				throw new KRouteException('unnamed', "Invalid route data");
			}
			if (!isset($route['name']))
			{
				throw new KRouteException('unnamed', 'Route must have a name.');
			}
			elseif (!isset($route['url']))
			{
				throw new KRouteException($route['name'], "Route must have a 'url' parameter.");
			}
			elseif (isset($route['defaults']) && !is_array($route['defaults']))
			{
				throw new KRouteException($route['name'], "Parameter 'defaults' must be an array.");
			}
			elseif (isset($route['constraints']) && !is_array($route['constraints']))
			{
				throw new KRouteException($route['name'], "Parameter 'constraints' must be an array.");
			}
			elseif (isset($route['constraints']) && !is_array($route['constraints']))
			{
				throw new KRouteException($route['name'], "Parameter 'constraints' must be an array.");
			}
			elseif (isset($route['casesensitive']) && !is_bool($route['casesensitive']))
			{
				throw new KRouteException($route['name'], "Parameter 'casesensitive' must be a boolean.");
			}
			elseif (isset($route['datatokens']) && !is_array($route['datatokens']))
			{
				throw new KRouteException($route['name'], "Parameter 'datatokens' must be an array.");
			}
			elseif (isset($route['routedelimiter']) && !is_string($route['routedelimiter']))
			{
				throw new KRouteException($route['name'], "Parameter 'routedelimiter' must be a string.");
			}
			return true;
		}
	}
}
